class Node:
    def __init__(self, val):
        self.val = val
        self.next = None


class QueueList:
    def __init__(self):
        queue = Node(0)
        self.front = queue
        self.rear = queue
        self.num = 0

    def is_empty(self):
        return self.front == self.rear

    def is_full(self):
        return False

    def enqueue(self, val):
        new_node = Node(val)
        self.rear.next = new_node
        self.rear = new_node
        self.num += 1

    def dequeue(self):
        if self.is_empty():
            raise Exception("Queue is empty")

        front_node = self.front
        self.front = front_node.next
        del front_node
        self.num -= 1

    def front(self):
        if self.is_empty():
            raise Exception("Queue is empty")

        return self.front.val

    def rear(self):
        if self.is_empty():
            raise Exception("Queue is empty")

        return self.rear

    def len(self):
        return self.num

    def __repr__(self):
        current = self.front
        values = []
        while current:
            values.append(current.val)
            current = current.next
        return f"num: {self.num}, values:{str(values)}"

    def show(self):
        print(self.__repr__())
